using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;

namespace ROVController
{
	public partial class CameraControl : UserControl
	{
		private const int SERVO_MAX_VALUE = 255;
		public event PositionUpdatedEventHandler PositionUpdated;

		public CameraControl()
		{
			InitializeComponent();
		}

		public string Label
		{
			get
			{
				return groupBox1.Text;
			}
			set
			{
				groupBox1.Text = value;
			}
		}

		//This function moves the Y axis slider when the mouse is clicked or held down in the camera panel and moved.
		private void panel1_MouseMove(object sender, MouseEventArgs e)
		{
			if (e.Button == MouseButtons.Left)
			{
				//-2 for the edge pixels plus -1 to allow for 0-based number 
				int maxMousePosition = this.panel1.Size.Height - 3;
				if (e.Y < 0)
				{
					this.sliderY.Value = SERVO_MAX_VALUE;
				}
				else if (e.Y > maxMousePosition)
				{
					this.sliderY.Value = 0;
				}
				else
				{
					//y is slightly more complicated than x because the mouse position is 0 at the top, while the slider is max at the top
					this.sliderY.Value = (int)Math.Round((double)(maxMousePosition - e.Y) / maxMousePosition * SERVO_MAX_VALUE);
				}
			}
		}

		private void sliderY_ValueChanged(object sender, EventArgs e)
		{
			//call any event handlers handling the PositionUpdated event
			byte value = (byte)this.sliderY.Value;
			PositionUpdated(this, new PositionEventArgs(value));
			txtValue.Text = value.ToString();
		}

		private Rectangle nonclipped;
		private void panel1_MouseDown(object sender, MouseEventArgs e)
		{
			//constrain the mouse to stay within the box while it is held down
			nonclipped = Cursor.Clip;
			Cursor.Clip = panel1.RectangleToScreen(panel1.ClientRectangle);
		}

		private void panel1_MouseUp(object sender, MouseEventArgs e)
		{
			Cursor.Clip = nonclipped;
		}

		private void txtValue_KeyDown(object sender, KeyEventArgs e)
		{
			if (e.KeyCode == Keys.Enter)
			{
				string input = txtValue.Text.Trim();
				try
				{
					this.sliderY.Value = byte.Parse(input);
				}
				catch
				{
					//revert value
					txtValue.Text = this.sliderY.Value.ToString();
				}
				txtValue.SelectAll();
			}
		}
	}

	public delegate void PositionUpdatedEventHandler(object sender, PositionEventArgs e);

	public class PositionEventArgs : EventArgs
	{
		private byte position;

		public PositionEventArgs(byte position)
		{
			this.position = position;
		}

		public byte Position
		{
			get
			{
				return this.position;
			}
		}
	}
}
